package hhm.android.account

import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import android.view.View
import android.widget.*
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.igexin.sdk.PushManager
import com.tencent.mm.opensdk.modelmsg.SendAuth
import hhm.android.account.databinding.ActivityLoginBinding
import hhm.android.library.bus.annotation.BusReceiver
import hhm.android.library.update.constant.UiType
import hhm.android.library.update.listener.OnBtnClickListener
import hhm.android.library.update.listener.OnInitUiListener
import hhm.android.library.update.model.UiConfig
import hhm.android.library.update.model.UpdateConfig
import hhm.android.library.update.ui.UpdateAppActivity
import hhm.android.library.update.update.UpdateAppUtils
import hhm.android.library.utils.DataStoreUtils
import hhm.android.library.utils.MatchUtils
import hhm.android.library.utils.OnMultiClickListener
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.first
import siau.android.base.*
import siau.android.http.model.CidRequest
import siau.android.http.model.UpdateRequest
import siau.android.library.KeyString

@Route(path = LOGIN_ROUTER)
class LoginActivity : SBBaseActivity(), TextWatcher, CompoundButton.OnCheckedChangeListener, CoroutineScope by MainScope() {

    private lateinit var loginModel: LoginViewModel
    private lateinit var dataBinding: ActivityLoginBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_login)
        loginModel = ViewModelProvider(this).get(LoginViewModel::class.java)
        dataBinding.viewModel = loginModel
        dataBinding.lifecycleOwner = this

        val showToast = intent.getBooleanExtra(KeyString.showToast, false)
        if (showToast) {
            showToast(getString(R.string.login_another_place))
        }

        when {
            HttpHelper.isPrepare() -> {
                dataBinding.activityLoginAround.visibility = View.VISIBLE
                dataBinding.activityLoginAround.text = "(预发布环境)"
            }
            HttpHelper.isInnerTest() -> {
                dataBinding.activityLoginAround.visibility = View.VISIBLE
                dataBinding.activityLoginAround.text = "(测试17环境)"
            }
            HttpHelper.isOuterTest() -> {
                dataBinding.activityLoginAround.visibility = View.VISIBLE
                dataBinding.activityLoginAround.text = "(测试环境(内网穿透))"
            }
        }

        async {
            val oldAlias = DataStoreUtils.readStringFromDataStore(KeyString.userAlias).first()
            if (oldAlias.isNullOrEmpty()) {
                PushManager.getInstance().unBindAlias(this@LoginActivity, oldAlias, true)
            }
            DataStoreUtils.writeStringToDataStore(KeyString.userAlias, "")
        }

        val startActivityForResult = registerForActivityResult(IntentIntActivityResultContact()) {
            if (it == 1024) {
                finish()
            }
        }

        dataBinding.activityLoginPrivacyAgreement.setOnClickListener(object : OnMultiClickListener() {
            override fun onMultiClick(v: View?) {
                ARouter.getInstance().build(WEBVIEW_ROUTER).withString(KeyString.url, SBApplication.privacyString).navigation()
            }
        })
        dataBinding.activityLoginUserAgreement.setOnClickListener(object : OnMultiClickListener() {
            override fun onMultiClick(v: View?) {
                ARouter.getInstance().build(WEBVIEW_ROUTER).withString(KeyString.url, SBApplication.usaString).navigation()
            }
        })

        loginModel.loginType.observe(this, {
            if (it == loginModel.PASSWORD_LOGIN) {
                dataBinding.activityLoginTopTitle.text = getString(R.string.password_login)
                dataBinding.activityLoginTopTitleTip.visibility = View.GONE
                dataBinding.activityLoginLoginType.text = getString(R.string.account_login)
                dataBinding.activityLoginCodeLl.visibility = View.GONE
                dataBinding.activityLoginPasswordLl.visibility = View.VISIBLE
                dataBinding.activityLoginForgetPassword.visibility = View.VISIBLE
                changeCanLogin()
            } else {
                dataBinding.activityLoginTopTitle.text = getString(R.string.account_login)
                dataBinding.activityLoginTopTitleTip.visibility = View.VISIBLE
                dataBinding.activityLoginLoginType.text = getString(R.string.password_login)
                dataBinding.activityLoginCodeLl.visibility = View.VISIBLE
                dataBinding.activityLoginPasswordLl.visibility = View.GONE
                dataBinding.activityLoginForgetPassword.visibility = View.GONE
                changeCanLogin()
            }
        })

        loginModel.errorString.observe(this, {
            hideLoadingDialog()
            showToast(it)
        })

        loginModel.dataLiveData.observe(this, {
            hideLoadingDialog()
            SBApplication.userData = it
            SBApplication.hasWeightMachine = false
            SBApplication.hasHeightMachine = false
            SBApplication.hasToothBrushMachine = false
            it.deviceList?.forEach { d ->
                if (d.deviceType == 1) {
                    SBApplication.hasWeightMachine = true
                } else if (d.deviceType == 2) {
                    SBApplication.hasHeightMachine = true
                } else if (d.deviceType == 3) {
                    SBApplication.hasToothBrushMachine = true
                }
            }

            PushManager.getInstance().bindAlias(this, SBApplication.userData.userAlias)
            async {
                DataStoreUtils.writeStringToDataStore(KeyString.userAlias, SBApplication.userData.userAlias)
            }

            if (loginModel.wxLoginLiveData.value?.userStatus == 0) {
                loginModel.loginType.value = loginModel.VERI_CODE_LOGIN
            }
            if (loginModel.loginType.value == loginModel.WX_LOGIN) {
                when (loginModel.wxLoginLiveData.value?.userStatus) {
                    1 -> {//正常
                        ARouter.getInstance().build(MAIN_ROUTER).navigation()
                        finish()
                    }
                    2 -> {//待添加家庭
                        startActivityForResult.launch(Intent(this, CreateLibraryOneActivity::class.java))
                    }
                    3 -> {//待选择身份
                        ARouter.getInstance().build(MAIN_ROUTER).withString(KeyString.loginType, "3").navigation()
                        finish()
                    }
                }
            } else {
                when (loginModel.loginLiveData.value?.userStatus) {
                    1 -> {//正常
                        ARouter.getInstance().build(MAIN_ROUTER).navigation()
                        finish()
                    }
                    2 -> {//待添加家庭
                        startActivityForResult.launch(Intent(this, CreateLibraryOneActivity::class.java))
                    }
                    3 -> {//待选择身份
                        ARouter.getInstance().build(MAIN_ROUTER).withString(KeyString.loginType, "3").navigation()
                        finish()
                    }
                }
            }
        })
        loginModel.wxLoginLiveData.observe(this, {
            if (TextUtils.isEmpty(it.token)) {
                //隐藏页面内容 让用户填写手机号
                loginModel.loginType.value = loginModel.VERI_CODE_LOGIN
                dataBinding.activityLoginLoginType.visibility = View.GONE
                dataBinding.activityLoginWx.visibility = View.GONE
                dataBinding.activityLoginWxTv.visibility = View.GONE
                loginModel.loginType.value = loginModel.WX_LOGIN
                loginModel.wxInfoId = it.wxInfoId
            } else {
                KeyString.token = it.token
                async {
                    DataStoreUtils.writeStringToDataStore(DataStoreUtils.TOKEN, it.token)
                    if (!TextUtils.isEmpty(SBApplication.cid) && !TextUtils.isEmpty(KeyString.token)) {
                        val cidRequest = CidRequest(SBApplication.cid)
                        HttpHelper().updateCid(cidRequest)?.subscribe({}, {})
                    }
                }
                loginModel.loginType.value = loginModel.WX_LOGIN
                when (it.userStatus) {
                    1 -> {//正常
                        showLoadingDialog()
                        loginModel.getDefaultFamily(lifecycle())
                    }
                    2 -> {//待添加家庭
                        startActivityForResult.launch(Intent(this, CreateLibraryOneActivity::class.java))
                    }
                    3 -> {//待选择身份
                        showLoadingDialog()
                        loginModel.getDefaultFamily(lifecycle())
                    }
                }
            }
        })

        loginModel.loginLiveData.observe(this, {
            KeyString.token = it.token
            async {
                DataStoreUtils.writeStringToDataStore(DataStoreUtils.TOKEN, it.token)

                if (!TextUtils.isEmpty(SBApplication.cid) && !TextUtils.isEmpty(KeyString.token)) {
                    val cidRequest = CidRequest(SBApplication.cid)
                    HttpHelper().updateCid(cidRequest)?.subscribe({}, {})
                }
            }
            when (it.userStatus) {
                1 -> {//正常
                    loginModel.getDefaultFamily(lifecycle())
                }
                2 -> {//待添加家庭
                    startActivityForResult.launch(Intent(this, CreateLibraryOneActivity::class.java))
                }
                3 -> {//待选择身份
                    loginModel.getDefaultFamily(lifecycle())
                }
            }
        })

        loginModel.canLogin.observe(this, {
            if (it) {
                dataBinding.activityLoginBtn.background = ContextCompat.getDrawable(this, R.drawable.rectangle_circle_maincolor)
            } else {
                dataBinding.activityLoginBtn.background = ContextCompat.getDrawable(this, R.drawable.rectangle_circle_grey_e6)
            }
        })

        loginModel.countDownNumber.observe(this, {
            if (it == 60) {
                dataBinding.activityLoginGetVerifyCode.text = getString(R.string.get_verify_code)
            } else {
                hideLoadingDialog()
                dataBinding.activityLoginGetVerifyCode.text = getString(R.string.re_get_verify_code_1) + it + getString(R.string.re_get_verify_code_2)
            }
        })

        dataBinding.activityLoginLoginType.setOnClickListener {
            if (loginModel.loginType.value == loginModel.VERI_CODE_LOGIN) {
                loginModel.loginType.value = loginModel.PASSWORD_LOGIN
            } else {
                loginModel.loginType.value = loginModel.VERI_CODE_LOGIN
            }
        }

        dataBinding.activityLoginPasswordCanSee.setOnClickListener {
            loginModel.showPassword = !loginModel.showPassword
            if (loginModel.showPassword) {
                dataBinding.activityLoginPasswordEt.transformationMethod = HideReturnsTransformationMethod.getInstance()
                dataBinding.activityLoginPasswordCanSee.setImageResource(R.mipmap.can_see)
            } else {
                dataBinding.activityLoginPasswordEt.transformationMethod = PasswordTransformationMethod.getInstance()
                dataBinding.activityLoginPasswordCanSee.setImageResource(R.mipmap.can_not_see)
            }
            dataBinding.activityLoginPasswordEt.setSelection(dataBinding.activityLoginPasswordEt.text.length)
        }

        dataBinding.activityLoginAccountEt.addTextChangedListener(this)
        dataBinding.activityLoginCodeEt.addTextChangedListener(this)
        dataBinding.activityLoginPasswordEt.addTextChangedListener(this)
        dataBinding.activityLoginCb.setOnCheckedChangeListener(this)

        dataBinding.activityLoginForgetPassword.setOnClickListener(object : OnMultiClickListener() {
            override fun onMultiClick(v: View?) {
                startActivityForResult.launch(Intent(this@LoginActivity, ForgetPasswordActivity::class.java))
            }
        })

        dataBinding.activityLoginGetVerifyCode.setOnClickListener {
            if (loginModel.canGetCode) {
                if (!loginModel.hasGetCode.value!!) {
                    loginModel.hasGetCode.value = true
                    loginModel.startCountDown(lifecycle(), dataBinding.activityLoginAccountEt.text.toString())
                }
            } else {
                showToast(getString(R.string.please_input_true_phone))
            }
        }

        dataBinding.activityLoginBtn.setOnClickListener(object : OnMultiClickListener() {
            override fun onMultiClick(v: View?) {
                if (loginModel.canLogin.value == true) {
                    showLoadingDialog()
                    if (loginModel.loginType.value == loginModel.PASSWORD_LOGIN) {
                        loginModel.passwordLogin(lifecycle(), dataBinding.activityLoginAccountEt.text.toString(), dataBinding.activityLoginPasswordEt.text.toString())
                    } else {
                        loginModel.smsLogin(lifecycle(), dataBinding.activityLoginAccountEt.text.toString(), dataBinding.activityLoginCodeEt.text.toString())
                    }
                }
            }
        })

        dataBinding.activityLoginWx.setOnClickListener(object : OnMultiClickListener() {
            override fun onMultiClick(v: View?) {
                val req = SendAuth.Req()
                req.scope = "snsapi_userinfo"
                req.state = "wechat_sdk_demo_test"
                SBApplication.api.sendReq(req)
            }
        })

        val b = UpdateRequest(SBApplication.version)
        HttpHelper().getUpdateInfo(b)?.subscribe({
            async {
                val intVersion = it.version.replace(".", "").toInt()
                val notNoticeVersion = DataStoreUtils.readIntFromDataStore(KeyString.isUpdateShow).first()

                if (notNoticeVersion == intVersion) {
                    return@async
                }

                when (it.updateType) {
                    0 -> {//不需要更新
                    }
                    1 -> {//普通更新

                        val uiConfig = UiConfig().apply {
                            uiType = UiType.CUSTOM
                            customLayoutId = R.layout.dialog_update
                            updateBtnText = getString(R.string.update_right_now)
                            cancelBtnText = getString(R.string.update_not_now)
                            downloadingToastText = getString(hhm.android.library.R.string.toast_download_apk)
                            downloadingBtnText = getString(hhm.android.library.R.string.downloading)
                            downloadFailText = getString(hhm.android.library.R.string.download_fail)
                        }

                        var cb: CheckBox? = null
                        UpdateAppUtils.getInstance(this@LoginActivity).apkUrl(it.link).updateTitle(getString(R.string.find_new_version)).uiConfig(uiConfig).updateContent(it.versionContent).setOnInitUiListener(object : OnInitUiListener {
                            override fun onInitUpdateUi(activity: UpdateAppActivity, view: View?, updateConfig: UpdateConfig, uiConfig: UiConfig) {
                                cb = view?.findViewById(R.id.dialog_update_cb)
                                view?.findViewById<ImageView>(R.id.dialog_update_update_x)?.setOnClickListener { _ ->
                                    if (cb?.isChecked == true) {
                                        writeVersionFunction(intVersion)
                                    }
                                    activity.checkIsClose()
                                }
                                view?.findViewById<LinearLayout>(R.id.dialog_update_not_notice_ll)?.setOnClickListener {
                                    cb?.isChecked = !cb?.isChecked!!
                                }
                                view?.findViewById<TextView>(R.id.dialog_update_version_tv)?.text = "V${it.version}"
                            }
                        }).setCancelBtnClickListener(object : OnBtnClickListener {
                            override fun onClick(): Boolean {
                                if (cb?.isChecked == true) {
                                    writeVersionFunction(intVersion)
                                }
                                return false
                            }
                        }).update()
                    }
                    else -> {
                        val uiConfig = UiConfig().apply {
                            uiType = UiType.CUSTOM
                            customLayoutId = R.layout.dialog_update
                            updateBtnText = getString(R.string.update_right_now)
                            cancelBtnText = ""
                            downloadingToastText = getString(hhm.android.library.R.string.toast_download_apk)
                            downloadingBtnText = getString(hhm.android.library.R.string.downloading)
                            downloadFailText = getString(hhm.android.library.R.string.download_fail)

                        }

                        UpdateAppUtils.getInstance(this@LoginActivity).apkUrl(it.link).updateTitle(getString(R.string.find_new_version)).uiConfig(uiConfig).updateContent(it.versionContent).setOnInitUiListener(object : OnInitUiListener {
                            override fun onInitUpdateUi(activity: UpdateAppActivity, view: View?, updateConfig: UpdateConfig, uiConfig: UiConfig) {
                                view?.findViewById<ImageView>(R.id.dialog_update_update_x)?.visibility = View.GONE
                                view?.findViewById<LinearLayout>(R.id.dialog_update_not_notice_ll)?.visibility = View.GONE
                                view?.findViewById<TextView>(R.id.dialog_update_version_tv)?.text = "V${it.version}"
                            }
                        }).updateConfig(UpdateConfig(force = true)).update()
                    }
                }
            }
        }, {})
    }

    private fun writeVersionFunction(intVersion: Int) {
        async {
            DataStoreUtils.writeIntToDataStore(KeyString.isUpdateShow, intVersion)
        }
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        changeCanLogin()
    }

    override fun afterTextChanged(s: Editable?) {
    }

    override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
        changeCanLogin()
    }

    private fun changeCanLogin() {
        loginModel.canGetCode = MatchUtils.isMobile(dataBinding.activityLoginAccountEt.text.toString())
        loginModel.canLogin.value = MatchUtils.isMobile(dataBinding.activityLoginAccountEt.text.toString()) && dataBinding.activityLoginCb.isChecked && ((loginModel.loginType.value == loginModel.PASSWORD_LOGIN && dataBinding.activityLoginPasswordEt.length() >= 6) || ((loginModel.loginType.value == loginModel.WX_LOGIN || loginModel.loginType.value == loginModel.VERI_CODE_LOGIN) && dataBinding.activityLoginCodeEt.length() == 6))
    }

    override fun finish() {
        super.finish()
        loginModel.finish()
    }

    @BusReceiver
    fun StringEvent(s: String) {
        if (s.startsWith(KeyString.wxLogin)) {
            loginModel.wxLoginData(s.replace(KeyString.wxLogin, ""))
        }
    }

}